import re

from rest_framework.viewsets import ViewSet
from django.db.models import Q

from .models import Projects, SystemDictData, Apis, ApiCase
from apps.schedule.models import Job
from .serializers import ProjectsSerializer, SystemDictDataSerializer, ApisSerializer, ApiCaseSerializer
from utils.response import *
from utils.params_filter import allow_edit, get_page


class ProjectsViewSet(ViewSet):
	serializer_class = ProjectsSerializer

	# 新增项目
	def create_project(self, request):
		# 允许修改的字段
		allow = ['name', 'protocol', 'host', 'desc', 'mark']
		data = allow_edit(allow, request)
		print(data)
		host = data.get('host')
		protocol = data.get('protocol')
		mark = data.get('mark')

		if not data.get('name'):
			return ErrorResponse(msg='name字段是必填项。')
		if not protocol:
			return ErrorResponse(msg='protocol字段是必填项。')
		elif not isinstance(protocol, int):
			return ErrorResponse(msg='protocol必输是整型')
		if not mark:
			return ErrorResponse(msg='mark字段是必填项。')
		elif Projects.objects.filter(mark=mark).filter(deleted=False):
			return ErrorResponse(msg='项目代码已存在')
		if not host:
			return ErrorResponse(msg='host字段是必填项。')
		elif not re.match(r'(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?',
						  host):
			return ErrorResponse(msg='URL 格式不正确', data={'host': host})
		else:
			Projects.objects.create(**data)
			return SuccessResponse(msg='创建成功')

	# 项目列表
	def list(self, request):
		projects = Projects.objects.filter(deleted=False).all()
		serializer = ProjectsSerializer(projects, many=True)
		return SuccessResponse(data={"list": serializer.data}, msg='调用成功')

	# 更新项目
	def update(self, request):
		# 允许修改的字段
		allow = ['name', 'protocol', 'mark', 'host', 'desc']
		data = allow_edit(allow, request)
		p_id = request.data.get('id')
		if not p_id:
			return ErrorResponse(msg='请求参数错误')
		project = Projects.objects.filter(id=p_id).filter(deleted=False)

		if not project:
			return ErrorResponse(msg='要修改的项目不存在')

		name = data.get('name')
		host = data.get('host')
		protocol = data.get('protocol')
		mark = data.get('mark')
		if not name:
			return ErrorResponse(msg='name字段是必填项。')
		if not protocol:
			return ErrorResponse(msg='protocol字段是必填项。')
		if not mark:
			return ErrorResponse(msg='mark字段是必填字段')

		t_project = Projects.objects.filter(mark=mark).filter(deleted=False)
		if t_project and t_project.first().id != p_id:
			return ErrorResponse(msg='项目代码已存在')
		if not host:
			return ErrorResponse(msg='host字段是必填项。')
		elif not re.match(r'(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?',
						  host):
			return ErrorResponse(msg='URL 格式不正确', data={'host': host})
		else:
			project.update(**data)
			serializer = ProjectsSerializer(project, many=True)
			return SuccessResponse(data=serializer.data, msg='调用成功')

	# 修改项目状态
	def change_status(self, request):
		p_id = request.data.get('id')
		if not p_id:
			return ErrorResponse(msg='请求参数错误')
		project = Projects.objects.filter(id=p_id).filter(deleted=False)
		if project:
			status = not project.first().status
			project.update(status=status)
			return SuccessResponse(msg='调用成功')
		else:
			return ErrorResponse(msg='项目不存在')

	# 删除项目
	def delete(self, request):
		p_id = request.data.get('id')
		if not p_id:
			return ErrorResponse(msg='请求参数错误')
		project = Projects.objects.filter(id=p_id).filter(deleted=False)
		if project:
			project.update(deleted=True)
			return SuccessResponse(msg='删除项目成功')
		else:
			return ErrorResponse(msg='项目不存在')

	# 获取项目详情
	def get_project_info(self, request):
		pId = request.query_params.get('id')
		print(pId)

		if not pId:
			return ErrorResponse(msg='请求参数错误')
		project = Projects.objects.filter(id=pId).filter(deleted=False)
		if project:
			return SuccessResponse(data=(ProjectsSerializer(project, many=True).data), msg='调用成功')
		else:
			return ErrorResponse(msg='获取数据失败')

	# 查询项目
	def search_project(self, request):
		query = request.query_params.get('query')
		if not query:
			return ErrorResponse(msg='请求参数错误')
		projects = Projects.objects.filter(
			Q(name__contains=query) | Q(mark__contains=query) | Q(host__contains=query)).filter(deleted=False)
		return SuccessResponse(data={'list': ProjectsSerializer(projects, many=True).data}, msg='调用成功')


class SystemDictDataViewSet(ViewSet):
	serializer_class = SystemDictDataSerializer

	# 添加系统字段
	def create(self, request):
		allow = ['dict_name', 'dict_value', 'dict_label', 'desc']
		data = allow_edit(allow, request)
		for param in allow:
			if not data.get(param) and param != 'desc':
				return ErrorResponse(msg=f'{param} 是必填项')
		SystemDictData.objects.create(**data)
		return SuccessResponse(msg='添加成功')

	def list(self, request):
		data = get_page(request, SystemDictData, SystemDictDataSerializer)
		return SuccessResponse(data=data, msg='调用成功')

	def update(self, request):
		# 允许修改的字段
		allow = ['dict_name', 'dict_value', 'dict_label', 'desc']
		data = allow_edit(allow, request)
		dict_id = request.data.get('id')
		if not dict_id:
			return ErrorResponse(msg='请求参数错误')
		dicts = SystemDictData.objects.filter(id=dict_id).filter(deleted=False)

		if not dicts:
			return ErrorResponse(msg='要修改的字典不存在')

		dict_name = data.get('dict_name')
		dict_value = data.get('dict_value')
		dict_label = data.get('dict_label')
		if not dict_name:
			return ErrorResponse(msg='dict_name字段是必填项。')
		if not dict_value:
			return ErrorResponse(msg='dict_value字段是必填项。')
		if not dict_label:
			return ErrorResponse(msg='dict_label字段是必填项。')
		else:
			dicts.update(**data)
			serializer = SystemDictDataSerializer(dicts, many=True)
			return SuccessResponse(data=serializer.data, msg='调用成功')

	# 修改字典状态
	def change_status(self, request):
		dict_id = request.data.get('id')
		if not dict_id:
			return ErrorResponse(msg='请求参数错误')
		dict = SystemDictData.objects.filter(id=dict_id).filter(deleted=False)
		if dict:
			status = not dict.first().status
			dict.update(status=status)
			return SuccessResponse(msg='调用成功')
		else:
			return ErrorResponse(msg='字典不存在')

	# 删除字典
	def delete(self, request):
		dict_id = request.query_params.get('id')
		if not dict_id:
			return ErrorResponse(msg='请求参数错误')
		system_dict = SystemDictData.objects.filter(id=dict_id, deleted=False)
		if system_dict:
			system_dict.update(deleted=True)
			return SuccessResponse(msg='删除成功')
		else:
			return ErrorResponse(msg='字典不存在或已删除')

	def query_dict_type_list(self, request):
		dict_type = request.query_params.get('dictType')
		if not dict_type:
			return ErrorResponse(msg='请求参数错误')

		dict_type_list = SystemDictData.objects.filter(dict_label=dict_type).filter(deleted=False)
		data = []
		for dict_info in dict_type_list:
			data.append({
				"id": dict_info.id,
				"dict_name": dict_info.dict_name,
				"dict_value": dict_info.dict_value,
				"dict_label": dict_info.dict_label,
				"desc": dict_info.desc
			})

		return SuccessResponse(data={'list': data}, msg='调用成功')

	# 获取字典详情
	def get_By_id(self, request):
		id = request.query_params.get('id')
		if not id:
			return ErrorResponse(msg='请求参数错误')

		system_dict = SystemDictData.objects.filter(id=id, deleted=False)
		if not system_dict:
			return ErrorResponse(msg='字典不存在或者已删除')
		return SuccessResponse(data=SystemDictDataSerializer(system_dict, many=True).data)


class ApisViewSet(ViewSet):
	serializer_class = ApisSerializer

	# 新建接口
	def create_api(self, request):
		allow = ['name', 'project_id', 'url', 'desc']
		data = allow_edit(allow, request)
		name = data.get('name')
		url = data.get('url')
		project_id = data.get('project_id')

		if not name:
			return ErrorResponse(msg='name字段是必填项')
		if not url:
			return ErrorResponse(msg='url字段是必填项')
		if not project_id:
			return ErrorResponse(msg='project_id字段是必填项')
		elif not Projects.objects.filter(id=project_id, deleted=False):
			return ErrorResponse(msg='项目不存在或已删除')
		Apis.objects.create(**data)
		return SuccessResponse(msg='添加成功')

	# 接口列表
	def list(self, request):
		serializer = ApisSerializer(Apis.objects.filter(deleted=False).all(), many=True)
		return SuccessResponse(data={"list": serializer.data}, msg='调用成功')

	# 修改接口
	def update(self, request):
		allow = ['name', 'project_id', 'url', 'desc']
		data = allow_edit(allow, request)
		api_id = request.data.get('id')
		if not api_id:
			return ErrorResponse(msg='请求参数错误')
		api = Apis.objects.filter(id=api_id).filter(deleted=False)
		if not api:
			return ErrorResponse(msg='要修改的api不存在')

		for param in allow:
			if not data.get(param) and param != 'desc':
				return ErrorResponse(msg=f'{param}字段是必填项')
		api.update(**data)
		serializer = ApisSerializer(api, many=True)
		return SuccessResponse(data=serializer.data, msg='修改成功')

	# 删除接口
	def delete(self, request):
		api_id = request.data.get('id')
		if not api_id:
			return ErrorResponse(msg='请求参数错误')
		apis = Apis.objects.filter(id=api_id).filter(deleted=False)
		if apis:
			apis.update(deleted=True)
			return SuccessResponse(msg='删除成功')
		else:
			return ErrorResponse(msg='接口不存在')

	# 获取接口详情
	def get_api_info(self, request):

		api_id = request.query_params.get('id')
		if not api_id:
			return ErrorResponse(msg='请求参数错误')
		api = Apis.objects.filter(id=api_id).filter(deleted=False)
		return SuccessResponse(data={"list": ApisSerializer(api, many=True).data}, msg='调用成功')

	# 查询接口
	def search(self, request):
		query = request.query_params.get('query')
		if not query:
			return ErrorResponse(msg='请求参数错误')
		apis = Apis.objects.filter(
			Q(name__contains=query) | Q(url__contains=query) | Q(project__mark__contains=query)).filter(deleted=False)
		return SuccessResponse(data={"list": ApisSerializer(apis, many=True).data})

	# 修改接口状态
	def change_status(self, request):
		id = request.query_params.get('id')
		if not id:
			return ErrorResponse(msg='请求参数错误')
		api = Apis.objects.filter(id=id, deleted=False)
		if not api:
			return ErrorResponse(msg='接口不存在或已删除')
		api.update(status=not api.first().status)
		return SuccessResponse(msg='接口状态已修改')


class CaseViewSet(ViewSet):

	# 添加用例
	def create(self, request):
		allow = ['api_id', 'case_name', 'request_type_id', 'headers', 'param_type_id', 'param', 'job_type_id',
				 'job_cron',
				 'desc', 'expect_type_id', 'expect']
		data = allow_edit(allow, request)
		api_id = data.get('api_id')
		if not api_id:
			return ErrorResponse(msg='请求参数错误')
		api = Apis.objects.filter(id=api_id, deleted=False).first()
		if not api:
			return ErrorResponse(msg='选择的接口不存在或已删除')
		for param in allow:
			if not data.get(param) and param != 'desc':
				return ErrorResponse(msg=f'{param} 是必填项')
		ApiCase.objects.create(**data)
		return SuccessResponse(msg='添加成功')

	# 用例列表
	def list_or_by_api_id(self, request):
		api_id = request.query_params.get('id')
		if not api_id:
			# 通过接口ID查询接口下的用例
			cases = ApiCase.objects.filter(deleted=False)
		else:
			# 查询用例列表
			cases = ApiCase.objects.filter(api_id=api_id, deleted=False)
		return SuccessResponse(data={"list": ApiCaseSerializer(cases, many=True).data})

	# 修改用例
	def update(self, request):
		case_id = request.data.get('id')
		if not case_id:
			return ErrorResponse(msg='请求参数错误')
		allow = ['case_name', 'request_type_id', 'headers', 'param_type_id', 'param', 'job_type_id',
				 'job_cron', 'desc', 'expect_type_id', 'expect']
		data = allow_edit(allow, request)
		if not ApiCase.objects.filter(id=case_id, deleted=False):
			return ErrorResponse(msg='修改的用例不存在或已删除')
		for param in allow:
			if not data.get(param) and param != 'desc':
				return ErrorResponse(msg=f'{param} 是必填项')
		ApiCase.objects.filter(id=case_id, deleted=False).update(**data)
		return SuccessResponse(msg='用例修改成功')

	# 删除用例
	def delete(self, request):
		case_id = request.query_params.get('id')
		if not case_id:
			return ErrorResponse(msg='请求参数错误')
		case = ApiCase.objects.filter(id=case_id, deleted=False)
		if not case:
			return ErrorResponse(msg='用例不存在或已删除')
		case.filter(id=case_id).update(deleted=True)
		return SuccessResponse(msg='删除成功')

	# 获取用例详情
	def get_by_id(self, request):
		case_id = request.query_params.get('id')
		if not case_id:
			return ErrorResponse(msg='请求参数错误')
		case = ApiCase.objects.filter(id=case_id, deleted=False)
		if not case:
			return ErrorResponse(msg='用力不存在或已删除')
		return SuccessResponse(data=ApiCaseSerializer(case, many=True).data)

	# 查询
	def search(self, request):
		query = request.query_params.get('query')
		api_id = request.query_params.get('id')
		if not api_id:
			return ErrorResponse(msg='请求参数错误')
		cases = ApiCase.objects.filter(Q(case_name__contains=query), api_id=api_id, deleted=False)
		return SuccessResponse(data={"list": ApiCaseSerializer(cases, many=True).data})

	def add_job(self, case):
		data = {}
		tmp_case = case
		data['url'] = tmp_case.api.project.host + tmp_case.api.url
		data['trigger'] = tmp_case.job_type.dict_value
		data['job_cron'] = tmp_case.job_cron
		data['params'] = tmp_case.param
		data['case_id'] = tmp_case.id
		# data['task_id'] = tmp_case.task_id
		data['job_status'] = not tmp_case.status
		return data

	# 修改接口状态
	def change_status(self, request):
		case_id = request.data.get('id')
		if not case_id:
			return ErrorResponse(msg='请求参数错误')
		case = ApiCase.objects.filter(id=case_id, deleted=False)
		if not case:
			return ErrorResponse(msg='用例不存在或已删除')

		job = Job.objects.filter(case_id=case_id, deleted=False)
		if not job:
			if case.first().status is False:
				data = self.add_job(case)
				Job.objects.create(**data)
		elif job.first().task_id == case.first().task_id:
			job.update(job_status=not case.first().status)
		elif case.first().status is False:
			job.update(deleted=True)
			data = self.add_job(case)
			Job.objects.create(**data)
		else:
			job.update(deleted=True)

		case.update(status=not case.first().status)
		return SuccessResponse(msg='状态修改成功')
